package configs

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"path"
)

type Config struct {
	Redis struct {
		Network  string `json:network`
		Address  string `json:address`
		Password string `json:password`
	}
	Mongodb struct {
		Uri string `json:uri`
		DB  string `json:db`
	}
	Mysql struct {
		Uri string `json:uri`
	}
	WeChat struct {
		AppID     string `json:AppID`
		AppSecret string `json:AppSecret`
	}
	Gitalk struct {
		ClientID     string   `json:ClientID`
		ClientSecret string   `json:ClientSecret`
		Repo         string   `json:Repo`
		Owner        string   `json:Owner`
		Admin        []string `json:Admin`
		ID           string   `json:ID`
	}
	FriendLinks struct {
		Column1 []struct {
			Name string `json:Name`
			Url  string `json:Url`
		}
		Column2 []struct {
			Name string `json:Name`
			Url  string `json:Url`
		}
	}

	Popularize []struct {
		Url   string `json:Url`
		Title string `json:Title`
		Img   string `json:Img`
	}

	runDir    string
	uploadDir string
	bingDir   string
	logDir    string
}

var instance Config

func init() {
	fmt.Println("configs init start")
	defer fmt.Println("configs init end")

	rundir, err := os.Getwd()
	if err != nil {
		panic(err)
	}

	text := AppDir("configs/configs.json")
	b, err := ioutil.ReadFile(text)
	if err != nil {
		panic(err)
	}

	instance.runDir = rundir
	err = json.Unmarshal(b, &instance)
	if err != nil {
		panic(err)
	}

	instance.uploadDir = path.Join(rundir, "view/upload")
	instance.bingDir = path.Join(rundir, "view/bing")
	instance.logDir = path.Join(rundir, "logs")
	dirs := []string{instance.uploadDir, instance.bingDir, instance.logDir}
	for _, v := range dirs {
		err = os.MkdirAll(v, os.ModePerm)
		if err != nil {
			panic(err)
		}
	}
}

func RunDir() string {
	return instance.runDir
}

func AppDir(subdir string) string {
	return path.Join(RunDir(), subdir)
}

func UploadDir() string {
	return instance.uploadDir
}

func BingDir() string {
	return instance.bingDir
}

func LogDir() string {
	return instance.logDir
}

func Instance() Config {
	return instance
}

func GitalkEncodingStr(id string) string {
	gitalk := instance.Gitalk
	gitalk.ID = id
	b, _ := json.Marshal(gitalk)
	for i, v := range b {
		b[i] = v ^ 0xE
	}
	return base64.StdEncoding.EncodeToString(b)
}
